package com.zenithmind.library.controller;

import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import com.zenithmind.library.pojo.dto.BookCopyCreateDTO;
import com.zenithmind.library.pojo.dto.BookCopyUpdateDTO;
import com.zenithmind.library.pojo.query.BookCopyQuery;
import com.zenithmind.library.pojo.vo.BookCopyVO;
import com.zenithmind.library.service.BookCopyService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 图书副本管理控制器
 * 遵循单一职责原则：只负责图书副本相关的HTTP请求处理
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@Slf4j
@RestController
@RequestMapping("/api/library/book-copies")
@RequiredArgsConstructor
@Tag(name = "图书副本管理", description = "图书副本的增删改查、状态管理、统计等功能")
public class BookCopyController {

    private final BookCopyService bookCopyService;

    @GetMapping("/page")
    @Operation(summary = "分页查询图书副本", description = "根据条件分页查询图书副本列表")
    @PreAuthorize("hasAuthority('library:book-copy:query')")
    public Result<PageResult<BookCopyVO>> getBookCopyPage(@Valid BookCopyQuery query) {
        log.info("分页查询图书副本，查询条件：{}", query);
        PageResult<BookCopyVO> result = bookCopyService.getBookCopyPage(query);
        return Result.success(result);
    }

    @GetMapping("/{id}")
    @Operation(summary = "查询图书副本详情", description = "根据ID查询图书副本详细信息")
    @PreAuthorize("hasAuthority('library:book-copy:query')")
    public Result<BookCopyVO> getBookCopyById(
            @Parameter(description = "图书副本ID", required = true)
            @PathVariable String id) {
        log.info("查询图书副本详情，ID：{}", id);
        return bookCopyService.getBookCopyById(id);
    }

    @GetMapping("/book/{bookId}")
    @Operation(summary = "查询图书的所有副本", description = "根据图书ID查询该图书的所有副本")
    @PreAuthorize("hasAuthority('library:book-copy:query')")
    public Result<List<BookCopyVO>> getBookCopiesByBookId(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId) {
        log.info("查询图书的所有副本，图书ID：{}", bookId);
        return bookCopyService.getBookCopiesByBookId(bookId);
    }

    @GetMapping("/barcode/{barcode}")
    @Operation(summary = "根据条形码查询图书副本", description = "通过条形码查询图书副本信息")
    @PreAuthorize("hasAuthority('library:book-copy:query')")
    public Result<BookCopyVO> getBookCopyByBarcode(
            @Parameter(description = "条形码", required = true)
            @PathVariable String barcode) {
        log.info("根据条形码查询图书副本，条形码：{}", barcode);
        return bookCopyService.getBookCopyByBarcode(barcode);
    }

    @PostMapping
    @Operation(summary = "创建图书副本", description = "创建新的图书副本")
    @PreAuthorize("hasAuthority('library:book-copy:create')")
    public Result<BookCopyVO> createBookCopy(@Valid @RequestBody BookCopyCreateDTO createDTO) {
        log.info("创建图书副本，参数：{}", createDTO);
        return bookCopyService.createBookCopy(createDTO);
    }

    @PostMapping("/batch")
    @Operation(summary = "批量创建图书副本", description = "为指定图书批量创建副本")
    @PreAuthorize("hasAuthority('library:book-copy:create')")
    public Result<List<BookCopyVO>> batchCreateBookCopies(
            @Parameter(description = "图书ID", required = true)
            @RequestParam String bookId,
            @Parameter(description = "创建数量", required = true)
            @RequestParam Integer quantity) {
        log.info("批量创建图书副本，图书ID：{}，数量：{}", bookId, quantity);
        return bookCopyService.batchCreateBookCopies(bookId, quantity);
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新图书副本", description = "更新图书副本信息")
    @PreAuthorize("hasAuthority('library:book-copy:update')")
    public Result<BookCopyVO> updateBookCopy(
            @Parameter(description = "图书副本ID", required = true)
            @PathVariable String id,
            @Valid @RequestBody BookCopyUpdateDTO updateDTO) {
        log.info("更新图书副本，ID：{}，参数：{}", id, updateDTO);
        return bookCopyService.updateBookCopy(id, updateDTO);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除图书副本", description = "删除指定的图书副本")
    @PreAuthorize("hasAuthority('library:book-copy:delete')")
    public Result<Void> deleteBookCopy(
            @Parameter(description = "图书副本ID", required = true)
            @PathVariable String id) {
        log.info("删除图书副本，ID：{}", id);
        return bookCopyService.deleteBookCopy(id);
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除图书副本", description = "批量删除多个图书副本")
    @PreAuthorize("hasAuthority('library:book-copy:delete')")
    public Result<Void> batchDeleteBookCopies(
            @Parameter(description = "图书副本ID列表", required = true)
            @RequestBody List<String> ids) {
        log.info("批量删除图书副本，数量：{}", ids.size());
        return bookCopyService.batchDeleteBookCopies(ids);
    }

    @PutMapping("/{id}/status")
    @Operation(summary = "更新图书副本状态", description = "更新图书副本的状态")
    @PreAuthorize("hasAuthority('library:book-copy:update')")
    public Result<Void> updateBookCopyStatus(
            @Parameter(description = "图书副本ID", required = true)
            @PathVariable String id,
            @Parameter(description = "状态", required = true)
            @RequestParam Integer status) {
        log.info("更新图书副本状态，ID：{}，状态：{}", id, status);
        return bookCopyService.updateBookCopyStatus(id, status);
    }

    @PutMapping("/{id}/location")
    @Operation(summary = "更新图书副本位置", description = "更新图书副本的存放位置")
    @PreAuthorize("hasAuthority('library:book-copy:update')")
    public Result<Void> updateBookCopyLocation(
            @Parameter(description = "图书副本ID", required = true)
            @PathVariable String id,
            @Parameter(description = "位置", required = true)
            @RequestParam String location) {
        log.info("更新图书副本位置，ID：{}，位置：{}", id, location);
        return bookCopyService.updateBookCopyLocation(id, location);
    }

    @GetMapping("/statistics/{bookId}")
    @Operation(summary = "获取图书副本统计", description = "获取指定图书的副本统计信息")
    @PreAuthorize("hasAuthority('library:book-copy:query')")
    public Result<BookCopyService.BookCopyStatisticsVO> getBookCopyStatistics(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId) {
        log.info("获取图书副本统计，图书ID：{}", bookId);
        return bookCopyService.getBookCopyStatistics(bookId);
    }

    @PostMapping("/import")
    @Operation(summary = "导入图书副本", description = "批量导入图书副本数据")
    @PreAuthorize("hasAuthority('library:book-copy:import')")
    public Result<String> importBookCopies(
            @Parameter(description = "图书副本数据列表", required = true)
            @RequestBody List<BookCopyCreateDTO> bookCopies) {
        log.info("导入图书副本，数量：{}", bookCopies.size());
        return bookCopyService.importBookCopies(bookCopies);
    }

    @PostMapping("/export")
    @Operation(summary = "导出图书副本", description = "根据条件导出图书副本数据")
    @PreAuthorize("hasAuthority('library:book-copy:export')")
    public Result<String> exportBookCopies(@RequestBody BookCopyQuery query) {
        log.info("导出图书副本，查询条件：{}", query);
        return bookCopyService.exportBookCopies(query);
    }

    @GetMapping("/barcode/exists")
    @Operation(summary = "检查条形码是否存在", description = "检查指定条形码是否已被使用")
    @PreAuthorize("hasAuthority('library:book-copy:query')")
    public Result<Boolean> checkBarcodeExists(
            @Parameter(description = "条形码", required = true)
            @RequestParam String barcode,
            @Parameter(description = "排除的副本ID")
            @RequestParam(required = false) String excludeId) {
        log.info("检查条形码是否存在，条形码：{}，排除ID：{}", barcode, excludeId);
        boolean exists = bookCopyService.existsByBarcode(barcode, excludeId);
        return Result.success(exists);
    }
}
